/*
    作者：zx
    时间：2022.11.10
    描述：硬件设备(device) 时钟中断处理
*/

#include "dev/time.h"
#include "comm/cpu_instr.h"
#include "os_cfg.h"
#include "cpu/irq.h"
#include "core/task.h"
// 系统时间片计数器
static uint32_t sys_tick;

// 定时器初始化
static void pit_init(void)
{
    // 1000毫秒 / 1000毫秒有多少节拍 = 1节拍多少毫秒 
    // 100毫秒 / 1节拍多少毫秒 = 多少节拍一次中断
    uint32_t reload_count = OS_TICKS_MS / ( 1000.0 / PIT_OSC_FREQ);
    outb(PIT_COMMAND_MODE_PORT,PIT_SELECT_COUNT0 | PIT_READ_LOAD | PIT_MODE);
    // 设置定时器初始值
    outb(PIT_CHANNEL0_DATA_PORT, reload_count & 0xff);
    outb(PIT_CHANNEL0_DATA_PORT, (reload_count>>8) & 0xff);

    // 安装时间片中断处理程序
    irq_install(IRQ0X20_TIMER,(uint32_t)exception_handler_time);
    // 打开8259A芯片 IRQ0引脚 端口号为0x20
    irq_enable(IRQ0X20_TIMER);

    
}

// 时间片中断
void time_init(void)
{
    sys_tick = 0;
    pit_init();
}


void do_handler_time(exception_frame_t * exception_frame){
    sys_tick++;
    irq_send_eoi(IRQ0X20_TIMER);
    // 更新运行程序的时间片计数，必须在eoi信号后面，保证正常执行
    // 先处理完成中断，再切换进程
    task_time_ticks();
}